package com.github.m6d21.sso.business.controller.role;

import com.github.m6d21.sso.common.util.EmptyUtil;
import com.github.m6d21.sso.model.role.dto.RolePermissionDTO;
import com.github.m6d21.sso.model.role.entity.Role;
import com.github.m6d21.sso.model.role.qo.RolePermissionQO;
import com.github.m6d21.sso.model.role.qo.RoleQO;
import com.github.m6d21.sso.model.role.vo.UnionRole;
import com.github.m6d21.sso.service.role.IRoleService;
import com.github.m6d21.sso.service.role.IUnionRoleService;
import com.github.m6d21.sso.support.annotation.RequestArrayParam;
import com.github.m6d21.sso.support.annotation.RequestDateParam;
import com.github.m6d21.sso.support.enums.StatusCode;
import com.github.m6d21.sso.support.model.Response;
import com.github.m6d21.sso.support.util.ResponseUtil;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 *<p>
 *账号api
 *</p>
 *
 * @author liuyang
 * @date 2018-12-07 Fri 13:27:00
 * @since 1.0.0
 */
@Api(value = "role", description = "角色api")
@Validated
@RestController
@RequestMapping("/web/role")
public class RoleController {

    @Resource
    private IRoleService roleService;

    @Resource
    private IUnionRoleService unionRoleService;

    @ApiOperation(value = "保存角色信息", httpMethod = "POST")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "name", value = "角色名称", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "roleCode", value = "角色编码", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "disable", value = "是否禁用", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "remark", value = "备注", paramType = "query", dataType = "string")})
    @PostMapping("/save")
    @ResponseBody
    public Response<Integer> saveRole(
        @NotBlank(message = "角色名称不能为空") @RequestParam("name") String name,
        @NotBlank(message = "角色编码不能为空") @RequestParam("roleCode") String roleCode,
        @RequestParam("disable") Integer disable,
        @RequestParam("remark") String remark) {
        Role role = new Role();
        role.setName(EmptyUtil.ifBlankToNull(name));
        role.setRoleCode(EmptyUtil.ifBlankToNull(roleCode));
        role.setDisable(disable);
        role.setRemark(EmptyUtil.ifBlankToNull(remark));
        role.setDisable(disable);
        roleService.saveRole(role);
        return ResponseUtil.success(role.getId());
    }

    @ApiOperation(value = "查询角色信息（包含角色信息）", httpMethod = "GET")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "pageNo", value = "页码(当前页)", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "pageSize", value = "分页大小", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "name", value = "角色名称", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "disable", value = "是否禁用", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "roleCode", value = "角色编码", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "startDate", value = "创建时间", paramType = "query", dataType = "date"),
        @ApiImplicitParam(name = "endDate", value = "创建时间", paramType = "query", dataType = "date")})
    @GetMapping("/query")
    @ResponseBody
    public Response<PageInfo<Role>> query(
        @RequestParam(value = "pageNo", required = false) Integer pageNo,
        @RequestParam(value = "pageSize", required = false) Integer pageSize,
        @RequestParam(value = "name", required = false) String name,
        @RequestParam(value = "disable", required = false) Integer disable,
        @RequestParam(value = "roleCode", required = false) String roleCode,
        @RequestDateParam(value = "startDate") Date startDate,
        @RequestDateParam(value = "endDate") Date endDate) {
        RoleQO roleQO = new RoleQO();
        roleQO.setName(EmptyUtil.ifBlankToNull(name));
        roleQO.setRoleCode(EmptyUtil.ifBlankToNull(roleCode));
        roleQO.setDisable(disable);
        roleQO.setStartDate(startDate);
        roleQO.setEndDate(endDate);
        return ResponseUtil.success(roleService.queryByPage(pageNo, pageSize, roleQO));
    }

    @ApiOperation(value = "查询角色信息（包含角色信息）", httpMethod = "GET")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "pageNo", value = "页码(当前页)", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "pageSize", value = "分页大小", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "name", value = "角色名称", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "disable", value = "是否禁用", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "roleCode", value = "角色编码", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "startDate", value = "创建时间", paramType = "query", dataType = "date"),
        @ApiImplicitParam(name = "endDate", value = "创建时间", paramType = "query", dataType = "date")})
    @GetMapping("/query/for/admin")
    @ResponseBody
    public Response<PageInfo<Role>> queryRoleForAdmin(
        @RequestParam(value = "pageNo", required = false) Integer pageNo,
        @RequestParam(value = "pageSize", required = false) Integer pageSize,
        @RequestParam(value = "name", required = false) String name,
        @RequestParam(value = "disable", required = false) Integer disable,
        @RequestParam(value = "roleCode", required = false) String roleCode,
        @RequestDateParam(value = "startDate") Date startDate,
        @RequestDateParam(value = "endDate") Date endDate) {
        RoleQO roleQO = new RoleQO();
        roleQO.setName(EmptyUtil.ifBlankToNull(name));
        roleQO.setRoleCode(EmptyUtil.ifBlankToNull(roleCode));
        roleQO.setDisable(disable);
        roleQO.setStartDate(startDate);
        roleQO.setEndDate(endDate);
        return ResponseUtil.success(roleService.queryByPageForAdmin(pageNo, pageSize, roleQO));
    }

    @ApiOperation(value = "修改角色信息（包含角色信息）", httpMethod = "POST")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "name", value = "角色名称", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "roleCode", value = "角色编码", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "disable", value = "是否禁用", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "remark", value = "备注", paramType = "query", dataType = "string")})
    @PostMapping("/modify")
    @ResponseBody
    public Response<Role> updateRole(
        @NotNull(message = "角色id不能为空") @RequestParam("id") Integer id,
        @RequestParam("name") String name,
        @RequestParam("roleCode") String roleCode,
        @RequestParam("disable") Integer disable,
        @RequestParam("remark") String remark) {
        Role role = new Role();
        role.setId(id);
        role.setName(EmptyUtil.ifBlankToNull(name));
        role.setRoleCode(EmptyUtil.ifBlankToNull(roleCode));
        role.setDisable(disable);
        role.setRemark(EmptyUtil.ifBlankToNull(remark));
        role.setDisable(disable);

        return ResponseUtil.success(roleService.modifyRoleById(role));
    }

    @ApiOperation(value = "根据角色ID删除角色", httpMethod = "POST")
    @ApiImplicitParam(name = "id", value = "角色ID", paramType = "query", dataType = "int")
    @PostMapping("/delete/id")
    @ResponseBody
    public Response deleteRoleById
        (@NotNull(message = "角色ID不能为空") @RequestParam("id") Integer id) {
        Boolean success = roleService.deleteRoleById(id);
        if (!success) {
            return ResponseUtil.fail(StatusCode.FAIL.getCode(), "删除失败");
        }
        return ResponseUtil.success();
    }

    @ApiOperation(value = "根据角色ID批量删除角色", httpMethod = "POST")
    @ApiImplicitParam(name = "ids", value = "角色ID数组", paramType = "query", dataType = "array")
    @PostMapping("/delete/ids")
    @ResponseBody
    public Response deleteRoleByIds
        (@NotNull(message = "角色ID不能为空") @RequestArrayParam(value = "ids", type = Integer.class) Integer[] ids) {
        Boolean success = roleService.deleteRoleByIds(Lists.newArrayList(ids));
        if (!success) {
            return ResponseUtil.fail(StatusCode.FAIL.getCode(), "删除失败");
        }
        return ResponseUtil.success();
    }

    @ApiOperation(value = "查询角色编码是否存在", httpMethod = "GET")
    @ApiImplicitParam(name = "roleCode", value = "角色编", paramType = "query", dataType = "string")
    @GetMapping("/exist/code")
    @ResponseBody
    public Response existByUsername(@RequestParam(value = "roleCode", required = false) String roleCode) {
        Boolean exist = roleService.existByRoleCode(roleCode);
        Map<String, Boolean> data = new HashMap<>();
        data.put("exist", exist);
        return ResponseUtil.success(data);
    }

    @ApiOperation(value = "查询角色信息（包含权限信息）", httpMethod = "GET")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "roleId", value = "角色id", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "roleName", value = "角色名称", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "roleCode", value = "角色编码", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "permissionId", value = "权限id", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = "permissionName", value = "权限名称", paramType = "query", dataType = "string"),
        @ApiImplicitParam(name = "permissionCode", value = "权限编码", paramType = "query", dataType = "string"),
    })
    @GetMapping("/query/with/permission")
    @ResponseBody
    public Response<List<UnionRole>> queryWithPermission(
        @RequestParam(value = "roleId", required = false) Integer roleId,
        @RequestParam(value = "roleName", required = false) String roleName,
        @RequestParam(value = "roleCode", required = false) String roleCode,
        @RequestParam(value = "permissionId", required = false) Integer permissionId,
        @RequestParam(value = "permissionName", required = false) String permissionName,
        @RequestParam(value = "permissionCode", required = false) String permissionCode) {
        RolePermissionQO rolePermissionQO = new RolePermissionQO();
        rolePermissionQO.setRoleId(roleId);
        rolePermissionQO.setRoleName(EmptyUtil.ifBlankToNull(roleName));
        rolePermissionQO.setRoleCode(EmptyUtil.ifBlankToNull(roleCode));
        rolePermissionQO.setPermissionId(permissionId);
        rolePermissionQO.setPermissionName(EmptyUtil.ifBlankToNull(permissionName));
        rolePermissionQO.setPermissionCode(EmptyUtil.ifBlankToNull(permissionCode));

        return ResponseUtil.success(unionRoleService.unionQuery(rolePermissionQO));
    }

    @ApiOperation(value = "给角色分配权限", httpMethod = "POST")
    @PostMapping("/save/role/permission/relations")
    @ResponseBody
    public Response saveRolePermissionRelations(
        @ApiParam(name = "roleId", value = "角色ID") @NotNull(message = "roleId不能为null") @RequestParam(value = "roleId", required = true) Integer roleId,
        @ApiParam(name = "permissionIds", value = "权限ID列表") @NotNull(message = "permissionIds不能为null") @RequestArrayParam(value = "permissionIds", type = Integer.class, required = true) Integer[] permissionIds) {
        List<Integer> permissionIdList = Lists.newArrayList(Optional.ofNullable(permissionIds).orElse(new Integer[0]));
        List<RolePermissionDTO> rolePermissionDTOList = new ArrayList<>(permissionIdList.size());
        permissionIdList.forEach(permissionId -> {
            RolePermissionDTO rolePermissionDTO = new RolePermissionDTO();
            rolePermissionDTO.setRoleId(roleId);
            rolePermissionDTO.setPermissionId(permissionId);
            rolePermissionDTOList.add(rolePermissionDTO);
        });
        unionRoleService.saveBatchRolePermissionRelation(rolePermissionDTOList);
        return ResponseUtil.success();
    }

    @ApiOperation(value = "给角色分配权限", httpMethod = "POST")
    @PostMapping("/alloc/permissions")
    @ResponseBody
    public Response allocPermissions(
        @ApiParam(name = "roleId", value = "角色ID") @NotNull(message = "roleId不能为null") @RequestParam(value = "roleId", required = true) Integer roleId,
        @ApiParam(name = "allocPermissionIds", value = "分配权限ID列表") @RequestArrayParam(value = "allocPermissionIds", type = Integer.class, required = false) Integer[] allocPermissionIds,
        @ApiParam(name = "deletePermissionIds", value = "删除权限ID列表") @RequestArrayParam(value = "deletePermissionIds", type = Integer.class, required = false) Integer[] deletePermissionIds) {
        List<Integer> allocPermissionIdList = Lists
            .newArrayList(Optional.ofNullable(allocPermissionIds).orElse(new Integer[0]));
        List<Integer> deletePermissionIdList = Lists
            .newArrayList(Optional.ofNullable(deletePermissionIds).orElse(new Integer[0]));

        unionRoleService.allocPermissions(roleId, allocPermissionIdList, deletePermissionIdList);
        return ResponseUtil.success();
    }
}
